;---------------------------------------------------------
;                 Player of PT2.x music
;---------------------------------------------------------

storehl: MACRO
 ld   a,l
 ld   [\1],a
 ld   a,h
 ld   [\1+1],a
ENDM

storede: MACRO
 ld   a,e
 ld   [\1],a
 ld   a,d
 ld   [\1+1],a
 ENDM

storebc: MACRO
 ld   a,c
 ld   [\1],a
 ld   a,b
 ld   [\1+1],a
ENDM

gethl: MACRO                      
 ld   hl,\1
 ld   a,[hli]
 ld   h,[hl]
 ld   l,a
ENDM

getbc: MACRO
 ld   a,[\1]
 ld   c,a
 ld   a,[\1+1]
 ld   b,a
 ENDM

getde: MACRO
 ld   a,[\1]
 ld   e,a
 ld   a,[\1+1]
 ld   d,a
 ENDM

;-Constants-----------------------------------------------

_plvChannelA equs "plvChannelA"
_plvChannelB equs "plvChannelB"
_plvChannelC equs "plvChannelC"

plaMASKA equ $10
plaMASKB equ $02
plaMASKC equ $44

plaEnvAddr:
 dw plaEnvDat0,plaEnvDat0,plaEnvDat0,plaEnvDat0
 dw plaEnvDat0,plaEnvDat0,plaEnvDat0,plaEnvDat0
 dw plaEnvDat8,plaEnvDat8,plaEnvDatA,plaEnvDatA
 dw plaEnvDat8,plaEnvDat8,plaEnvDatA,plaEnvDatA

plaEnvDat0:
 rept 16
 db   0
 endr
plaEnvDat8:
 db   $01,$23,$45,$67,$89,$ab,$cd,$ef
 db   $01,$23,$45,$67,$89,$ab,$cd,$ef
plaEnvDatA:
 db   $01,$23,$45,$67,$89,$ab,$cd,$ef
 db   $fe,$dc,$ba,$98,$76,$54,$32,$10

plaEnvelopeV:
 Incbin "music/sounde.bin"
plaNotes:
 Incbin "music/soundt.bin"
plaNotes1:
 Incbin "music/soundt1.bin"

plaVolumes:
 Incbin "music/volume.bin"

;-Main-initializatin----------------------------

plaStop:
 xor  a
 ldh  [$24],a
 ldh  [$25],a
 ret

plaInitMusic:
 storehl plvMusic
 ld   a,[hl+]
 ld   [plvDelay],a
 ld   a,[hl+]
 ld   [plvMusLen],a
 ld   a,[hl+]
 ld   [plvLoopTo],a
 storehl plvSampAddrs
 ld   de,32
 add  hl,de
 add  hl,de
 storehl plvOrnAddrs
 add  hl,de
 ld   c,[hl]
 inc  hl
 ld   b,[hl]
 inc  hl
 storebc plvPatAddrs
 ld   e,131-101
 add  hl,de
 storehl plvPosAddrs

 xor  a
 ld   b,13
 ld   hl,plvOrnAddrA
 ld   [hli],a
 dec  b
 jr   nz,@-2

 dec  a
 ld   [plvNoteA],a
 ld   [plvNoteB],a
 ld   [plvNoteC],a
 dec  a
 ld   [plvONoise],a
 ld   [plvONoiseV],a
 ld   [plvOVolumeA],a
 ld   [plvOVolumeB],a
 ld   [plvOVolumeC],a

 ld   a,$0f
 ld   [plvVolumeA],a
 ld   [plvVolumeB],a
 ld   [plvVolumeC],a

 ld   a,1
 ld   [plvDelayC],a
 jr   plaNextPos

plaFromBegin:
 ld   a,[plvLoopTo]
 ld   [plvPos],a
plaNextPos:
 ld   hl,plvPos
 ld   a,[hl]
 inc  [hl]
 ld   e,a
 ld   d,0
 gethl plvPosAddrs
 add  hl,de
 ld   a,[hl]
 cp   $ff
 jr   z,plaFromBegin

 ld   l,a
 ld   h,d    ;d=0
 ld   e,a
 add  hl,hl  ;*2
 add  hl,de  ;*3
 add  hl,hl  ;*6
 getde plvPatAddrs
 add  hl,de
 getde plvMusic
 add  hl,de

 ld   c,[hl]
 inc  hl
 ld   b,[hl]
 inc  hl
 push hl
 ld   h,d
 ld   l,e
 add  hl,bc
 storehl _plvChannelA
 pop  hl
 ld   c,[hl]
 inc  hl
 ld   b,[hl]
 inc  hl
 push hl
 ld   h,d
 ld   l,e
 add  hl,bc
 storehl _plvChannelB
 pop  hl
 ld   c,[hl]
 inc  hl
 ld   b,[hl]
 inc  hl
 push hl
 ld   h,d
 ld   l,e
 add  hl,bc
 storehl _plvChannelC
 pop  hl
 ld   a,1
 ld   [plvNoteLeftA],a
 ld   [plvNoteLeftB],a
 ld   [plvNoteLeftC],a

plaNextNote:

;-Channel-A-------------------------------------
 
plaNextNoteA:
 ld   hl,plvNoteLeftA
 dec  [hl]
 jp   nz,plaNextNoteAEnd
 gethl plvChannelA
 ld   a,[hl]
 or   a
 jp   z,plaNextPos
plaNextNoteA1:
 ld   a,[hl+]
 or   a
 jr   z,plaNextPosA
 add  a,$20
 jr   c,plaNextNoteA2
 add  a,$60
 jr   c,plaNextNoteA3
 add  a,$10
 jp   c,plaNextNoteA4
 add  a,$10
 jp   c,plaNextNoteA5
 add  a,$40
 jp   c,plaNextNoteA7
 add  a,$10
 jp   c,plaNextNoteA8
 add  a,$10
 cp   $0f
 jr   nz,@+3
 inc  hl
 cp   $0e
 jr   nz,@+3
 inc  hl
 cp   $0d
 jr   nz,@+5
 inc  hl
 inc  hl
 inc  hl
 cp   $0c
 jr   z,plaNextNoteA1
 ld   a,[hl+]
 ld   [plvNoiseAddA],a
 jr   plaNextNoteA1

plaNextPosA:
 dec  hl
plaNextNoteAExit:
 ld   a,[plvNoteDelA]
 ld   [plvNoteLeftA],a
 storehl plvChannelA
 jp   plaNextNoteAEnd

plaNextNoteA2:
 or   a
 jr   nz,plaNextNoteA2D
 dec  a     ; a=$ff
 ld   [plvNoteA],a
 jr   plaNextNoteAExit
plaNextNoteA2D
 push hl
 add  a,a
 ld   l,a
 ld   h,0
 getde plvSampAddrs
 add  hl,de
 ld   e,[hl]
 inc  hl
 ld   d,[hl]
 gethl plvMusic
 add  hl,de
 ld   a,[hl+]
 ld   [plvSampQuarksA],a
 ld   a,[hl+]
 ld   [plvSampQuarkTA],a
 storehl plvSampAddrA
 pop  hl
 jp   plaNextNoteA1

plaNextNoteA3:
 ld   [plvNoteA],a
 xor  a
 ld   [plvSampQuarkA],a
 ld   [plvOrnQuarkA],a
 jp   plaNextNoteAExit

plaNextNoteA4:
 jr   z,plaNextNoteAExit  ;plaNextNoteA1
 cp   $0f
 jr   nz,@+3
 xor  a  
 ld   [plvEnvelopeA],a
 jp   z,plaNextNoteA1
 ld   e,[hl]
 inc  hl
 ld   d,[hl]
 inc  hl
 storede plvEnvelope
 jp   plaNextNoteA1

plaNextNoteA5:
 push hl
 ld   hl,0
 jr   z,plaNextNoteA6
 add  a,a
 ld   l,a
 getde plvOrnAddrs
 add  hl,de
 ld   e,[hl]
 inc  hl
 ld   d,[hl]
 inc  hl
 gethl plvMusic
 add  hl,de
 ld   a,[hl+]
 ld   [plvOrnQuarksA],a
 ld   a,[hl+]
 ld   [plvOrnQuarkTA],a
plaNextNoteA6:
 storehl plvOrnAddrA
 pop  hl
 jp   plaNextNoteA1

plaNextNoteA7:
 inc  a
 ld   [plvNoteDelA],a
 jp   plaNextNoteA1

plaNextNoteA8:
 ld   [plvVolumeA],a
 jp   plaNextNoteA1

plaNextNoteAEnd:

;-Channel-A-End---------------------------------

;-Channel-B-------------------------------------
 
plaNextNoteB:
 ld   hl,plvNoteLeftB
 dec  [hl]
 jp   nz,plaNextNoteBEnd
 gethl plvChannelB
plaNextNoteB1:
 ld   a,[hl+]
 or   a
 jr   z,plaNextPosB
 add  a,$20
 jr   c,plaNextNoteB2
 add  a,$60
 jr   c,plaNextNoteB3
 add  a,$10
 jp   c,plaNextNoteB4
 add  a,$10
 jp   c,plaNextNoteB5
 add  a,$40
 jp   c,plaNextNoteB7
 add  a,$10
 jp   c,plaNextNoteB8
 add  a,$10
 cp   $0f
 jr   nz,@+3
 inc  hl
 cp   $0e
 jr   nz,@+3
 inc  hl
 cp   $0d
 jr   nz,@+5
 inc  hl
 inc  hl
 inc  hl
 cp   $0c
 jr   z,plaNextNoteB1
 ld   a,[hl+]
 ld   [plvNoiseAddB],a
 jr   plaNextNoteB1

plaNextPosB:
 dec  hl
plaNextNoteBExit:
 ld   a,[plvNoteDelB]
 ld   [plvNoteLeftB],a
 storehl plvChannelB
 jp   plaNextNoteBEnd

plaNextNoteB2:
 or   a
 jr   nz,plaNextNoteB2D
 ld   a,$ff
 ld   [plvNoteB],a
 jr   plaNextNoteBExit
plaNextNoteB2D
 push hl
 add  a,a
 ld   l,a
 ld   h,0
 getde plvSampAddrs
 add  hl,de
 ld   e,[hl]
 inc  hl
 ld   d,[hl]
 gethl plvMusic
 add  hl,de
 ld   a,[hl+]
 ld   [plvSampQuarksB],a
 ld   a,[hl+]
 ld   [plvSampQuarkTB],a
 storehl plvSampAddrB
 pop  hl
 jp   plaNextNoteB1

plaNextNoteB3:
 ld   [plvNoteB],a
 xor  a
 ld   [plvSampQuarkB],a
 ld   [plvOrnQuarkB],a
 jp   plaNextNoteBExit

plaNextNoteB4:
 jp   z,plaNextNoteBExit ;plaNextNoteB1
 cp   $0f
 jr   nz,@+3
 xor  a
 ld   [plvEnvelopeB],a
 jp   z,plaNextNoteB1
 ld   e,[hl]
 inc  hl
 ld   d,[hl]
 inc  hl
 storede plvEnvelope
 jp   plaNextNoteB1

plaNextNoteB5:
 push hl
 ld   hl,0
 jr   z,plaNextNoteB6
 add  a,a
 ld   l,a
 getde plvOrnAddrs
 add  hl,de
 ld   e,[hl]
 inc  hl
 ld   d,[hl]
 inc  hl
 gethl plvMusic
 add  hl,de
 ld   a,[hl+]
 ld   [plvOrnQuarksB],a
 ld   a,[hl+]
 ld   [plvOrnQuarkTB],a
plaNextNoteB6:
 storehl plvOrnAddrB
 pop  hl
 jp   plaNextNoteB1

plaNextNoteB7:
 inc  a
 ld   [plvNoteDelB],a
 jp   plaNextNoteB1

plaNextNoteB8:
 ld   [plvVolumeB],a
 jp   plaNextNoteB1

plaNextNoteBEnd:

;-Channel-B-End---------------------------------

;-Channel-C-------------------------------------
 
plaNextNoteC:
 ld   hl,plvNoteLeftC
 dec  [hl]
 jp   nz,plaNextNoteCEnd
 gethl plvChannelC
plaNextNoteC1:
 ld   a,[hl+]
 or   a
 jr   z,plaNextPosC
 add  a,$20
 jr   c,plaNextNoteC2
 add  a,$60
 jr   c,plaNextNoteC3
 add  a,$10
 jp   c,plaNextNoteC4
 add  a,$10
 jp   c,plaNextNoteC5
 add  a,$40
 jp   c,plaNextNoteC7
 add  a,$10
 jp   c,plaNextNoteC8
 add  a,$10
 cp   $0f
 jr   nz,@+3
 inc  hl
 cp   $0e
 jr   nz,@+3
 inc  hl
 cp   $0d
 jr   nz,@+5
 inc  hl
 inc  hl
 inc  hl
 cp   $0c
 jr   z,plaNextNoteC1
 ld   a,[hl+]
 ld   [plvNoiseAddC],a
 jr   plaNextNoteC1

plaNextPosC:
 dec  hl
plaNextNoteCExit:
 ld   a,[plvNoteDelC]
 ld   [plvNoteLeftC],a
 storehl plvChannelC
 jp   plaNextNoteCEnd

plaNextNoteC2:
 or   a
 jr   nz,plaNextNoteC2D
 dec  a
 ld   [plvNoteC],a
 jr   plaNextNoteCExit
plaNextNoteC2D
 push hl
 add  a,a
 ld   l,a
 ld   h,0
 getde plvSampAddrs
 add  hl,de
 ld   e,[hl]
 inc  hl
 ld   d,[hl]
 gethl plvMusic
 add  hl,de
 ld   a,[hl+]
 ld   [plvSampQuarksC],a
 ld   a,[hl+]
 ld   [plvSampQuarkTC],a
 storehl plvSampAddrC
 pop  hl
 jp   plaNextNoteC1

plaNextNoteC3:
 ld   [plvNoteC],a
 xor  a
 ld   [plvSampQuarkC],a
 ld   [plvOrnQuarkC],a
 jp   plaNextNoteCExit

plaNextNoteC4:
 jp   z,plaNextNoteCExit  ;plaNextNoteC1
 cp   $0f
 jr   nz,@+3
 xor  a
 ld   [plvEnvelopeC],a
 jp   z,plaNextNoteC1
 ld   e,[hl]
 inc  hl
 ld   d,[hl]
 inc  hl
 storede plvEnvelope
 jp   plaNextNoteC1

plaNextNoteC5:
 push hl
 ld   hl,0
 jr   z,plaNextNoteC6
 add  a,a
 ld   l,a
 getde plvOrnAddrs
 add  hl,de
 ld   e,[hl]
 inc  hl
 ld   d,[hl]
 inc  hl
 gethl plvMusic
 add  hl,de
 ld   a,[hl+]
 ld   [plvOrnQuarksC],a
 ld   a,[hl+]
 ld   [plvOrnQuarkTC],a
plaNextNoteC6:
 storehl plvOrnAddrC
 pop  hl
 jp   plaNextNoteC1

plaNextNoteC7:
 inc  a
 ld   [plvNoteDelC],a
 jp   plaNextNoteC1

plaNextNoteC8:
 ld   [plvVolumeC],a
 jp   plaNextNoteC1
plaPlayMusic:
 ld   hl,plvDelayC
 dec  [hl]
 jr   nz,plaSamples
 jp   plaNextNote

plaNextNoteCEnd:

;-Channel-C-End---------------------------------

 ld   a,[plvDelay]
 ld   [plvDelayC],a

plaSamples:
 ld   a,plaMASKA|plaMASKB|plaMASKC
 ld   [plvChannels],a
 xor  a
 ld   [plvDVolumeA],a
 ld   [plvDVolumeB],a
 ld   [plvDVolumeC],a
 ld   [plvNVolumeA],a
 ld   [plvNVolumeB],a
 ld   [plvNVolumeC],a
 dec  a
 ld   [plvNoise],a

;-Sample-for-channel-A--------------------------
 
plaSampA:
 ld   a,[plvNoteA]
 inc  a
 jp   z,plaSampAEnd

 getde plvOrnAddrA
 ld   a,d
 or   e
 jr   z,plaSampA5
 ld   hl,plvOrnQuarkA
 ld   a,[hl]
 inc  [hl]
 ld   hl,plvOrnQuarksA
 cp   [hl]
 jr   c,plaSampA4
 ld   a,[plvOrnQuarkTA]
 ld   [plvOrnQuarkA],a
plaSampA4:
 ld   l,a
 ld   h,0
 getde plvOrnAddrA
 add  hl,de
 ld   a,[hl]
 bit  7,a
 jr   z,plaSampA5
 and  $3f
 cpl
 inc  a
plaSampA5:
 ld   b,a

 ld   hl,plvSampQuarkA
 ld   a,[hl]
 inc  [hl]
 ld   hl,plvSampQuarksA
 cp   [hl]
 jr   c,plaSampA2
 ld   a,[plvSampQuarkTA]
 ld   [plvSampQuarkA],a
plaSampA2:
 ld   l,a
 add  a,a
 add  a,l
 ld   l,a
 ld   h,0
 getde plvSampAddrA
 add  hl,de

 ld   a,[hl]
 bit  0,a
 jr   nz,plaSampA3
 rra
 rra
 rra
 and  $1f
 ld   [plvNoise],a
 ld   a,$11
 ld   [plvNoiseC],a
plaSampA3:

 ld   c,[hl]
 inc  hl
 ld   a,[hl]
 and  15
 ld   d,a
 inc  hl
 ld   e,[hl]
 dec  hl
 bit  2,c
 jr   z,plaSampA1
 ld   a,e
 cpl
 ld   e,a
 ld   a,d
 cpl
 ld   d,a
 inc  de
plaSampA1:
 push de

 ld   a,[hl]
 swap a
 and  15
 ld   l,a
 ld   a,[plvVolumeA]
 dec  a
 swap a
 or   l
 ld   l,a
 ld   h,0
 ld   de,plaVolumes
 add  hl,de
 ld   a,[hl]
 ld   [plvNVolumeA],a
 bit  1,c
 jr   z,@+3
 xor  a
 ld   [plvDVolumeA],a

 ld   a,[plvNoteA]
 add  a,b
 bit  7,b
 jr   z,@+3
 ccf
 jr   nc,@+3
 xor  a
 cp   $60
 jr   c,@+4
 ld   a,$5f
 add  a,a
 ld   l,a
 ld   h,0
 ld   de,plaNotes
 add  hl,de
 pop  de
 ld   a,[hl+]
 ld   h,[hl]
 ld   l,a
 ld   a,h
 and  $f8
 jr   z,@+5
 ld   hl,0
 add  hl,de

 storehl plvDToneA

plaSampAEnd:

;-End-of-sample-for-channel-A-------------------

;-Sample-for-channel-B--------------------------

plaSampB:
 ld   a,[plvNoteB]
 inc  a
 jp   z,plaSampBEnd

 getde plvOrnAddrB
 ld   a,d
 or   e
 jr   z,plaSampB5
 ld   hl,plvOrnQuarkB
 ld   a,[hl]
 inc  [hl]
 ld   hl,plvOrnQuarksB
 cp   [hl]
 jr   c,plaSampB4
 ld   a,[plvOrnQuarkTB]
 ld   [plvOrnQuarkB],a
plaSampB4:
 ld   l,a
 ld   h,0
 getde plvOrnAddrB
 add  hl,de
 ld   a,[hl]
 bit  7,a
 jr   z,plaSampB5
 and  $3f
 cpl
 inc  a
plaSampB5:
 ld   b,a

 ld   hl,plvSampQuarkB
 ld   a,[hl]
 inc  [hl]
 ld   hl,plvSampQuarksB
 cp   [hl]
 jr   c,plaSampB2
 ld   a,[plvSampQuarkTB]
 ld   [plvSampQuarkB],a
plaSampB2:
 ld   l,a
 add  a,a
 add  a,l
 ld   l,a
 ld   h,0
 getde plvSampAddrB
 add  hl,de

 ld   a,[hl]
 bit  0,a
 jr   nz,plaSampB3
 srl  a
 srl  a
 srl  a
 ld   [plvNoise],a
 ld   a,$22
 ld   [plvNoiseC],a
plaSampB3:

 ld   c,[hl]
 inc  hl
 ld   a,[hli]
 and  15
 ld   d,a
 ld   e,[hl]
 dec  hl
 bit  2,c
 jr   z,plaSampB1
 ld   a,e
 cpl
 ld   e,a
 ld   a,d
 cpl
 ld   d,a
 inc  de
plaSampB1:
 push de
 ld   a,[hl]
 swap a
 and  15
 ld   l,a
 ld   a,[plvVolumeB]
 dec  a
 swap a
 or   l
 ld   l,a
 ld   h,0
 ld   de,plaVolumes
 add  hl,de
 ld   a,[hl]
 ld   [plvNVolumeB],a
 bit  1,c
 jr   z,@+3
 xor  a
 ld   [plvDVolumeB],a
 ld   a,[plvNoteB]
 add  a,b
 bit  7,b
 jr   z,@+3
 ccf
 jr   nc,@+3
 xor  a
 cp   $60
 jr   c,@+4
 ld   a,$5f
 add  a,a
 ld   l,a
 ld   h,0
 ld   de,plaNotes
 add  hl,de

 pop  de
 ld   a,[hl+]
 ld   h,[hl]
 ld   l,a
 ld   a,h
 and  $f8
 jr   z,@+5
 ld   hl,0
 add  hl,de
 storehl plvDToneB

plaSampBEnd:

;-End-of-sample-for-channel-B-------------------

;-Sample-for-channel-C--------------------------

plaSampC:
 ld   a,[plvNoteC]
 inc  a
 jp   z,plaSampCEnd

 getde plvOrnAddrC
 ld   a,d
 or   e
 jr   z,plaSampC5
 ld   hl,plvOrnQuarkC
 ld   a,[hl]
 inc  [hl]
 ld   hl,plvOrnQuarksC
 cp   [hl]
 jr   c,plaSampC4
 ld   a,[plvOrnQuarkTC]
 ld   [plvOrnQuarkC],a
plaSampC4:
 ld   l,a
 ld   h,0
 getde plvOrnAddrC
 add  hl,de
 ld   a,[hl]
 bit  7,a
 jr   z,plaSampC5
 and  $3f
 cpl
 inc  a
plaSampC5:
 ld   b,a
 ld   hl,plvSampQuarkC
 ld   a,[hl]
 inc  [hl]
 ld   hl,plvSampQuarksC
 cp   [hl]
 jr   c,plaSampC2
 ld   a,[plvSampQuarkTC]
 ld   [plvSampQuarkC],a
plaSampC2:
 ld   l,a
 add  a,a
 add  a,l
 ld   l,a
 ld   h,0
 getde plvSampAddrC
 add  hl,de

 ld   a,[hl]
 bit  0,a
 jr   nz,plaSampC3
 srl  a
 srl  a
 srl  a
 ld   [plvNoise],a
 ld   a,$44
 ld   [plvNoiseC],a
plaSampC3:
 ld   c,[hl]
 inc  hl
 ld   a,[hl]
 and  15
 ld   d,a
 inc  hl
 ld   e,[hl]
 dec  hl
 bit  2,c
 jr   z,plaSampC1
 ld   a,e
 cpl
 ld   e,a
 ld   a,d
 cpl
 ld   d,a
 inc  de
plaSampC1:
 push de
 ld   a,[hl]
 swap a
 and  15
 ld   l,a
 ld   a,[plvVolumeC]
 dec  a
 swap a
 or   l
 ld   l,a
 ld   h,0
 ld   de,plaVolumes
 add  hl,de
 ld   a,[hl]
 ld   [plvNVolumeC],a
 bit  1,c
 jr   z,@+3
 xor  a
 ld   [plvDVolumeC],a
 ld   a,[plvNoteC]
 add  a,b
 bit  7,b
 jr   z,@+3
 ccf
 jr   nc,@+3
 xor  a
 cp   $60
 jr   c,@+4
 ld   a,$5f
 add  a,a
 ld   l,a
 ld   h,0
 ld   de,plaNotes1
 add  hl,de
 pop  de
 ld   a,[hl+]
 ld   h,[hl]
 ld   l,a
 add  hl,de
 ld   a,h
 and  $f8
 jr   z,@+5
 ld   hl,0
 storehl plvDToneC

plaSampCEnd:

;-End-of-sample-for-channel-C-------------------

;-Creating-envelope----

 ld   a,[plvEnvelope+1]
 or   a
 jp   nz,plvOutEE
 ld   a,[plvEnvelope]
 ld   l,a
 ld   h,0
 add  hl,hl
 ld   de,plaEnvelopeV
 add  hl,de
 ld   a,[hl+]
 ld   h,[hl]
 ld   l,a

 ld   a,h
 and  $f8
 jp   nz,plvOutEE

 getde plvDToneC
 ld   a,[plvDVolumeC]
 ld   c,a
 ld   b,0

 push hl
 ld   a,[plvVolumeA]
 or   a
 jr   nz,plvOutE1
 ld   a,[plvEnvelopeA]
 or   a
 jr   z,plvOutE1
 ld   b,a
 ld   a,c
 ld   [plvDVolumeA],a
 storede plvDToneA
 ld   a,[plvChannels]
 ld   l,a
 and  %10101010
 ld   h,a
 ld   a,l
 and  $11
 add  a,a
 add  a,a
 or   h
 ld   h,a
 ld   a,l
 and  $44
 rrca
 rrca
 or   h
 ld   [plvChannels],a
plvOutE1:
 ld   a,[plvVolumeB]
 or   a
 jr   nz,plvOutE2
 ld   a,[plvEnvelopeB]
 or   a
 jr   z,plvOutE2
 ld   b,a
 ld   a,c
 ld   [plvDVolumeB],a
 storede plvDToneB
 ld   a,[plvChannels]
 ld   l,a
 and  %10101010
 ld   h,a
 ld   a,l
 and  $22
 add  a,a
 or   h
 ld   h,a
 ld   a,l
 and  $44
 rrca
 or   h
 ld   [plvChannels],a
plvOutE2:
 ld   a,[plvVolumeC]
 or   a
 jr   nz,plvOutE3
 ld   a,[plvEnvelopeC]
 or   a
 jr   z,plvOutE3
 ld   b,a
plvOutE3:
 pop  hl
 ld   a,b
 or   a
 jr   z,plvOutEE
 add  a,$10
 ld   [plvDVolumeC],a
 storehl plvDToneC
plvOutEE:

;-Channel-A---

 xor  a
 ldh  [$10],a
 ld   b,a
 ld   a,$80
 ldh  [$11],a
 ld   hl,plvDVolumeA
 ld   a,[plvOVolumeA]
 cp   [hl]
 jr   z,plaOutA1
 ld   a,[plvDVolumeA]
 swap a
 ldh  [$12],a
 ld   b,$80
plaOutA1:

 gethl plvDToneA
 ld   a,l
 ldh  [$13],a
 ld   a,h
 or   b
 ldh  [$14],a

 ld   a,[plvDVolumeA]
 ld   [plvOVolumeA],a

;-Channel-B---

 ld   a,$80
 ldh  [$16],a

 ld   b,0
 ld   hl,plvDVolumeB
 ld   a,[plvOVolumeB]
 cp   [hl]
 jr   z,plaOutB1
 ld   a,[plvDVolumeB]
 swap a
 ldh  [$17],a
 ld   b,$80
plaOutB1:

 gethl plvDToneB
 ld   a,l
 ldh  [$18],a
 ld   a,h
 or   b
 ldh  [$19],a

 ld   a,[plvDVolumeB]
 ld   [plvOVolumeB],a

;-Channel-C---

 ld   b,0
 ld   a,[plvOVolumeC]
 ld   hl,plvDVolumeC
 cp   [hl]
 jr   z,plaOutC3
 xor  a
 ldh  [$1a],a
 ld   a,%00100000
 ldh  [$1c],a
 xor  a
 ldh  [$1b],a
 ld   a,[hl]
 cp   $10
 jr   c,plaOutCE1
 sub  $10
 add  a,a
 ld   l,a
 ld   h,0
 ld   de,plaEnvAddr
 add  hl,de
 ld   a,[hl+]
 ld   h,[hl]
 ld   l,a
 ld   de,$ff30
 rept 16
 ld   a,[hl+]
 ld   [de],a
 inc  e
 endr
 jr   plaOutCE2
plaOutCE1:
 ld   c,a
 swap a
 or   c
 ld   hl,$ff30
 ld   b,0
 rept 2
 rept 4
 ld   [hl+],a
 endr
 rept 4
 ld   [hl],b
 inc  l
 endr
 endr
plaOutCE2:
 ld   a,$80
 ldh  [$1a],a
 ld   b,a
plaOutC3:

 gethl plvDToneC
 ld   a,l
 ldh  [$1d],a
 ld   a,h
 or   b
 ldh  [$1e],a

 ld   a,[plvDVolumeC]
 ld   [plvOVolumeC],a

;-Channel-N---
 
 xor  a
 ldh  [$20],a

 ld   b,a
 ld   c,a
 ld   a,[plvNoise]
 inc  a
 jr   z,plaOutN0

 ld   hl,plvChannels
 ld   a,[plvNoiseC]
 bit  1,a
 jr   nz,plaOutN3
 bit  2,a
 jr   nz,plaOutN4
 and  [hl]
 rlca
 rlca
 rlca
 ld   hl,plvNVolumeA
 ld   b,a
 ld   a,[plvNoiseAddA]
 jr   plaOutN1
plaOutN3:
 and  [hl]
 rlca
 rlca
 ld   hl,plvNVolumeB
 ld   b,a
 ld   a,[plvNoiseAddB]
 jr   plaOutN1
plaOutN4:
 and  [hl]
 rlca
 ld   hl,plvNVolumeC
 ld   b,a
 ld   a,[plvNoiseAddC]
plaOutN1:
 ld   d,a
 ld   c,[hl]
plaOutN0:

 ld   e,0
 ld   a,[plvNoise]
 add  a,d
 and  $1f
 srl  a
 srl  a
 ld   hl,plvONoise
 cp   [hl]
 jr   z,plaOutN6
 ld   [hl],a
 or   $30
 ldh  [$22],a
plaOutN6:
 ld   a,c
 ld   hl,plvONoiseV
 cp   [hl]
 jr   z,plaOutN5
 ld   [hl],a
 swap a
 ldh  [$21],a

 ld   e,$80
plaOutN5:
 ld   a,e
 ldh  [$23],a

 ld   a,c
 or   a
 jr   z,plaOutN2
 ld   a,[plvChannels]
 or   b
 ld   [plvChannels],a
plaOutN2:
;-Complete----

 ld   a,$ff
 ldh  [$24],a
 ld   a,[plvChannels]
 ldh  [$25],a
 ret

